import requests
import json
import matplotlib.pyplot as plt
import seaborn as sns
from wordcloud import WordCloud
import pandas as pd
font = "simfang.ttf"
headers = {'user-agent': 'Mozilla/5.0'}
stopword = ['一','二','三','四','五']


def getHTMLText(url):
    try:
        r = requests.get(url, headers=headers)
        r.raise_for_status()
        r.encoding = r.apparent_encoding
        return r.text
    except:
        return ""


def parse(html, videolist):
    data = json.loads(html)
    whether = data['data']['list']['vlist']  # 判断该页视频是否为空
    if whether:
        for i in range(len(data['data']['list']['vlist'])):
            title = data['data']['list']['vlist'][i]['title']
            play  = data['data']['list']['vlist'][i]['play']
            comment = data['data']['list']['vlist'][i]['comment']
            aid   = data['data']['list']['vlist'][i]['aid']
            videolist.append({
                "title" : title,
                "play"  : play,
                "comment":comment,
                "aid"   : aid
            })

    return whether


def plot_data(df, filename):
    df['play'] = pd.to_numeric(df['play'])
    df['comment'] = pd.to_numeric(df['comment'])

    fig, ax1 = plt.subplots(figsize=(12, 6))

    # 绘制 'play' 的折线图
    color1 = 'tab:red'
    ax1.set_xlabel('Time')
    ax1.set_ylabel('Playback', color=color1)
    ax1.tick_params(axis='y', labelcolor=color1)
    sns.lineplot(data=df.iloc[::-1], x='title', y='play', color=color1)
    ax1.tick_params(axis='x', which='both', bottom=False, labelbottom=False)

    # 禁用 'play' 的 y轴上的科学计数法
    ax1.ticklabel_format(style='plain', axis='y')

    # 添加 'comment' 的折线图
    ax2 = ax1.twinx()
    color2 = 'tab:blue'
    ax2.set_ylabel('Comment', color=color2)
    ax2.tick_params(axis='y', labelcolor=color2)
    sns.lineplot(data=df.iloc[::-1], x='title', y='comment', color=color2)

    # 设置图像标题和坐标轴标签
    plt.title('Video Status')
    plt.xlabel('Time')
    plt.ylabel('Comment')

    # 隐藏 x 轴刻度和标签
    plt.tick_params(axis='x', which='both', bottom=False, labelbottom=False)

    # 设置图例
    lines, labels = ax1.get_legend_handles_labels()
    lines2, labels2 = ax2.get_legend_handles_labels()
    ax2.legend(lines + lines2, labels + labels2, loc='upper left')

    plt.savefig(filename)
    plt.show()

def plot_wordcloud(df, filename):
    # 将 'title' 列数据合并为一个字符串
    titles = ' '.join(df['title'].tolist())

    # 初始化 WordCloud 对象
    wc = WordCloud(font_path=font, width=1600, height=800, mode='RGBA', collocations=False, stopwords=stopword, background_color='white', prefer_horizontal=1.0).generate(titles)

    image = wc.to_image()
    image.show()
    wc.to_file(filename)



def main():
    print("请输入Up主的uid和简称，程序将统计其视频播放量，评论量，并生成视频标题词云")
    uid = input("请输入Up主uid：")
    author = input("请输入Up主简称：")
    videolist = []
    for i in range(1,100):
        print(i)
        url = "https://api.bilibili.com/x/space/arc/search?mid=" + str(uid) + "&pn=" + str(i) + "&ps=25&index=1&jsonp=jsonp"
        html = getHTMLText(url)
        whether = parse(html, videolist)
        if not whether:  # 没视频了
            break
    df = pd.DataFrame(videolist, columns=['title', 'play', 'comment','aid'])
    df.to_excel(author + "的视频状况统计.xlsx")
    plot_data(df, author+"的视频状况统计.png")
    plot_wordcloud(df, author+"视频标题词云.png")


main()